/**
 * 
 * @author Marina Polese
 *
 */

package capture;

import java.awt.BorderLayout;
import java.util.List;
import java.util.Vector;

import javax.swing.JComponent;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreePath;

import jpcap.packet.Packet;
import capture.analyzer.AbstractPacketAnalyzer;

public class PacketProtocolTree extends JComponent {

	private static final long serialVersionUID = 497158696253896552L;
	private JTree tree;
	private DefaultMutableTreeNode root = new DefaultMutableTreeNode();
	private List<AbstractPacketAnalyzer> analyzers = PacketAnalyzerLoader.getAnalyzers();

	public PacketProtocolTree(){
		initialize();
	}

	private void initialize() {
		tree = new JTree(root);
		tree.setRootVisible(false);
		JScrollPane treeView = new JScrollPane(tree);

		setLayout(new BorderLayout());
		add(treeView,BorderLayout.CENTER);
	}

	public void analyzePacket(Packet packet){
		boolean[] isExpanded=new boolean[root.getChildCount()];
		for(int i=0;i<root.getChildCount();i++)
			isExpanded[i] = tree.isExpanded(new TreePath(((DefaultMutableTreeNode)root.getChildAt(i)).getPath()));

		root.removeAllChildren();

		DefaultMutableTreeNode node;
		for(AbstractPacketAnalyzer analyzer:analyzers){
			if(analyzer.isAnalyzable(packet)){
				analyzer.analyze(packet);
				node=new DefaultMutableTreeNode(analyzer.getProtocolName());
				root.add(node);
				String[] names=analyzer.getValueNames();
				Object[] values=analyzer.getValues();
				if(names==null) continue;

				for(int j=0;j<names.length;j++){
					if(values[j] instanceof Vector){
						addNodes(node,names[j],(Vector<?>)values[j]);
					}else if(values[j]!=null){
						addNode(node,names[j]+": "+values[j]);
					}
				}
			}
		}
		((DefaultTreeModel)tree.getModel()).nodeStructureChanged(root);

		for(int i=0;i<Math.min(root.getChildCount(),isExpanded.length);i++)
			if(isExpanded[i]) tree.expandPath(new TreePath(((DefaultMutableTreeNode)root.getChildAt(i)).getPath()));
	}

	private void addNode(DefaultMutableTreeNode node,String str){
		node.add(new DefaultMutableTreeNode(str));
	}

	private void addNodes(DefaultMutableTreeNode node,String str,Vector<?> v){
		DefaultMutableTreeNode subnode=new DefaultMutableTreeNode(str);

		for(int i=0;i<v.size();i++)
			subnode.add(new DefaultMutableTreeNode(v.elementAt(i)));

		node.add(subnode);
	}

	public void clear(){

	}
}
